package com.itkf.core.listener;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itkf.core.config.DtpProperties;
import com.itkf.core.lifecycle.DtpRegistry;
import com.itkf.core.config.ThreadPoolProperties;
import com.itkf.core.configCenter.ConfigChangeListener;
import com.itkf.core.executor.DtpExecutor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@RequiredArgsConstructor
public class DtpConfigChangeListener implements ConfigChangeListener {
    private final ObjectMapper objectMapper;
    private final DtpProperties dtpProperties;
    private final DtpRegistry dtpRegistry;
    @Override
    public void onChange(String newConfig) {
        try {
            // 解析新配置
            DtpProperties newProperties = objectMapper.readValue(newConfig, DtpProperties.class);

            // 校验并更新配置
            updateThreadPools(newProperties);
        } catch (Exception e) {
            log.error("Process config change failed", e);
        }
    }

    //TODO 参数验证 + 配置变动 + 获取上一次的配置文件
    private void updateThreadPools(DtpProperties newProperties) {
        for (ThreadPoolProperties newPoolConfig : newProperties.getExecutors()) {
            String poolName = newPoolConfig.getThreadPoolName();

            // 获取已注册的线程池
            DtpExecutor executor = dtpRegistry.getDtpExecutor(poolName);
            if (executor == null) {
                log.warn("ThreadPool [{}] not registered, skip update", poolName);
                continue;
            }


            //校验队列类型不可变
//             ThreadPoolProperties oldConfig = getOriginalConfig(poolName);
//            if (!oldConfig.getQueueType().equals(newPoolConfig.getQueueType())) {
//                log.error("Queue type modification not allowed for pool [{}]", poolName);
//                continue;
//            }

            ThreadPoolProperties oldConfig = null;
            // 应用新配置
            applyNewConfig(executor, oldConfig, newPoolConfig);
        }
    }

    private void applyNewConfig( DtpExecutor executor,
                                ThreadPoolProperties oldConfig,
                                ThreadPoolProperties newConfig) {
        // 核心线程数变更
        if (newConfig.getCorePoolSize() != oldConfig.getCorePoolSize()) {
            executor.setCorePoolSize(newConfig.getCorePoolSize());
        }

        // 最大线程数变更
        if (newConfig.getMaxPoolSize() != oldConfig.getMaxPoolSize()) {
            executor.setMaximumPoolSize(newConfig.getMaxPoolSize());
        }

        // 空闲时间变更
        if (!newConfig.getKeepAliveTime().equals(oldConfig.getKeepAliveTime())) {
            executor.setKeepAliveTime(newConfig.getKeepAliveTime().toMillis(), TimeUnit.MILLISECONDS);
        }

        // 拒绝策略变更
        if (!newConfig.getRejectedPolicyType().equals(oldConfig.getRejectedPolicyType())) {
            executor.setRejectedHandler(newConfig.getRejectedPolicyType());
        }

        log.info("ThreadPool [{}] config updated successfully", newConfig.getThreadPoolName());
    }
}
